using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Threading;
using JigLibX.Physics;
using JigLibX.Collision;
using JigLibX.Geometry;
using Microsoft.Xna.Framework.Input.Touch;
using Services;
using Utilities;

namespace WAS.Logic.SampleLevel
{
    using Geometry = Body;
    using Game = Microsoft.Xna.Framework.Game;

    /// <summary>
    ///Implementa la gestionde degli asteroidi
    /// </summary>
    /// 
    public abstract class AsteroidsLayer : ShipsLayer
    {
        static protected readonly float MINIMUM_ASTEROID_SIZE = 0.4f;
        static protected readonly float LIFE_SIZE_RATE = 200f;
        static protected readonly float LIFE_MASS_RATE = 50f;
      
        public AsteroidsLayer(Game game, BaseLevelStats current_score, int num_lives)
            : base(game, current_score, num_lives)
        {
        }

        protected override void UpdateAsteroids(float dt)
        {
            

            for (int i = 0; i < CurrentState.asteroids.Count; i++)
            {

                
                //Si controlla la distanza con (diagonalSize / 1.8) in quanto gli asteroidi vengono creati ad un raggio di (diagonalSize / 2)
                if (Vector3.Distance(CurrentState.asteroids[i].geometry.Position, Vector3.Zero) > (diagonalSize / 1.8))
                {
                    RemoveAsteroid(i);
                    CurrentState.RemoveAsteroidAt(i);
                    i--;
                }
            }
        }


        protected void createAsteroid(Vector3 position, float life, Vector3 direction)
        {
            float size = life / LIFE_SIZE_RATE;
            Stats stat = new Stats() { CurrentLife = life, MaxLife = life, NumberOfSquash = 0 };
            var new_asteroid = new Asteroid(true) // costruttore NON di default: alloca questa reference nel pool
            {
                stat = stat,
                geometry = PhysicsHelper.create_sphere(new BoundingSphere(position, scene_service.Asteroid.BoundingSphere.Radius * size),
                                                       direction, life * LIFE_MASS_RATE, null),
                size = size,
            };
            for (int i = 0; i < CurrentState.enemies.Count; i++)
            {
                new_asteroid.geometry.CollisionSkin.NonCollidables.Add(CurrentState.enemies[i].geometry.CollisionSkin);
            }
            for (int i = 0; i < CurrentState.bosses.Count; i++)
            {
                new_asteroid.geometry.CollisionSkin.NonCollidables.Add(CurrentState.bosses[i].geometry.CollisionSkin);
            }
            new_asteroid.geometry.ExternalData = new_asteroid;
            //new_asteroid.geometry.AngularVelocity = Vector3.Up;
            CurrentState.asteroids.Add(new_asteroid);
        }

        protected void RemoveAsteroid(int index)
        {
            var p = CurrentState.asteroids[index];
            physics.RemoveBody(p.geometry);
            //if (true)
            //{
            //    NewExplosions.Add(new Explosion(true)
            //    {
            //        explosion_type = ExplosionType.Asteroid,
            //        originating_asteroid = p.OwnValue,
            //        position = p.geometry.Position
            //    });
            //}
        }


        protected override Vector3 asteroidsFreeSpace(Vector3 position, Vector3 direction, BoundingSphere bs)
        {
            direction.Normalize();
            var free = true;
            do
            {
                for (int i = 0; i < CurrentState.asteroids.Count; i++)
                {
                    var a = CurrentState.asteroids[i];
                    free = free && !a.geometry.bounding_sphere().Intersects(bs);
                    if (!free)
                    {
                        position += direction * (Vector3.Distance(a.geometry.bounding_sphere().Center, bs.Center)) * 2;
                        break;
                    }
                }
            }
            while (free == false);
            return position;
        }

    }
}
